"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTemplateUrl = void 0;
const path_1 = __importDefault(require("path"));
const crypto_1 = __importDefault(require("crypto"));
const ora_1 = __importDefault(require("ora"));
const core_1 = require("../core");
/**
 * Get template url.
 * @param input template name or uri
 * @example
 * 1. short name, e.g. 'nm'
 * 2. full name, e.g. 'zce/nm'
 * 3. with branch, e.g. 'zce/nm#next'
 * 4. full url, e.g. 'https://github.com/zce/nm/archive/master.zip'
 */
const getTemplateUrl = async (input) => {
    if (/^https?:/.test(input))
        return input;
    input = input.includes('/') ? input : `${core_1.config.official}/${input}`;
    input = input.includes('#') ? input : `${input}#${core_1.config.branch}`;
    const [owner, name, branch] = input.split(/\/|#/);
    const data = { owner, name, branch };
    return core_1.config.registry.replace(/{(.*?)}/g, (_, key) => data[key]);
};
exports.getTemplateUrl = getTemplateUrl;
/**
 * Resolve template from remote or local.
 */
exports.default = async (ctx) => {
    // '~/foo/bar' in windows  windows 目录
    if (ctx.template.startsWith('~')) {
        ctx.src = core_1.file.untildify(ctx.template);
        return;
    }
    // local template path   从本地拉取模板文件
    if (/^[./]|^[a-zA-Z]:/.test(ctx.template)) {
        ctx.src = path_1.default.resolve(ctx.template);
        return;
    }
    // fetch remote template  获取远程的目录图片
    const url = await exports.getTemplateUrl(ctx.template);
    // url hash (16 digit md5)
    const hash = crypto_1.default.createHash('md5').update(url).digest('hex').substr(8, 16);
    // template cache path
    ctx.src = path_1.default.join(core_1.config.paths.cache, hash);
    // template cache exist
    const exists = await core_1.file.isDirectory(ctx.src);
    if (ctx.options.offline != null && ctx.options.offline) {
        // offline mode
        if (exists) { // 通过本地的缓存模板直接拿出来用
            // found cached template
            return console.log(`Using cached template: \`${core_1.file.tildify(ctx.src)}\`.`);
        }
        console.log(`Cache not found: \`${core_1.file.tildify(ctx.src)}\`.`);
    }
    // clear cache
    exists && await core_1.file.remove(ctx.src);
    const spinner = ora_1.default('Downloading template...').start();
    try {
        // download template zip
        const temp = await core_1.http.download(url);
        // extract template
        await core_1.file.extract(temp, ctx.src, 1);
        // clean up
        await core_1.file.remove(temp);
        spinner.succeed('Download template complete.');
    }
    catch (e) {
        spinner.stop();
        throw new Error(`Failed to pull \`${ctx.template}\` template: ${e.message}.`);
    }
};
